<?php
/**
 * ===============================================
 * 版权所有 2019-2050 青岛铁锤科技有限公司，并保留所有权利。
 * 网站地址: http://www.huaxianling.com
 * ===============================================
 * Author: Happy dong
 * Created Time: 2019-07-04 17:10
 *
 * Version: 2.0
 */

namespace App\Modules\Order\Repositories;


use App\Models\GoodsOrder;
use App\Models\MemberCard;
use App\Models\Order;
use App\Models\Royalty;
use App\Modules\Employee\Repositories\EmployeeRepository;
use App\Modules\Employee\Repositories\EmployeeRoyaltyRepository;
use App\Modules\Order\Criterias\getRoyaltyDataCriteria;
use App\Modules\Order\Validators\RoyaltyValidator;
use App\Modules\Store\Repositories\StoreRepository;
use Flower\Core\Repository\Eloquent\BaseRepository;
use function foo\func;

class RoyaltyRepository extends BaseRepository
{
	public function model()
	{
		return Royalty::class;
	}

	public function validator()
	{
		return RoyaltyValidator::class;
	}


	/**
	 * 订单完成插入用户提成
	 * @param $barberId
	 * @param $storeId
	 * @param $orderId
	 * @param $realPrice
	 * @param $royalty
	 * @param $checkAmount
	 * @param int $type
	 * @param int $paymentRoyalty
	 * @return mixed
	 */
	public function addOrderRoyalty($barberId, $storeId, $orderId, $realPrice, $royalty, $checkAmount, $type = 1, $paymentRoyalty = 100)
	{
		// 组织数据
		$base = [
			'user_id' => $barberId,
			'store_id' => $storeId,
			'type' => $type,
			'item_type'=> $type ==1 ? Order::class : $type==2 ? MemberCard::class : GoodsOrder::class,
			'item_id' => $orderId,
			'price' => $realPrice
		];
		$data = [
			'check_amount' => $checkAmount,
			'rate' => isset($royalty) ? $royalty : 0,
			'amount' => empty($royalty) ? 0 : round(($checkAmount * $royalty * $paymentRoyalty * 0.0001), 2)
		];
		return $this->updateOrCreate($base, $data);
	}

	/**
	 * 计算单个理发师或单个店铺的今日提成 实时提成
	 * @param int $userId
	 * @param $storeId
	 * @param array $type
	 * @param $today
	 * @return mixed
	 */
	public function getUserStoreTodayRoyalty($userId = 0, $storeId = 0, $type = [], $today = 0)
	{
		$type = empty($type) ? [config('constant.royaltyType.service'), config('constant.royaltyType.goods'), config('constant.royaltyType.card')] : $type;
		$map = empty($userId) ? ['store_id' => $storeId] : ['user_id' => $userId, 'store_id' => $storeId];
		// 提成求和
		$data['list'] = $this->model->where($map)->whereDate('created_at', $today)->whereIn('type', $type)->selectRaw('count(id) as nums, sum(amount) as amount, type')->groupBy('type')->get()->toArray();
		// 指定字段为key值 直接更加type值取指定的提成
		$data['list'] = !empty($data['list']) ? array_column($data['list'], null, 'type') : [];
		// 二维数组求和
		$data['amount'] = !empty($data['list']) ? array_reduce($data['list'], function ($result, $v) {
			return $result + $v['amount'];
		}) : 0;
		return $data;
	}

	/**
	 * 理发师一周提成
	 * @param $requestData
	 * @return array
	 */
	public function weekRoyalty($requestData)
	{
		$storeId = $requestData['store_id'];
		$userId = $requestData['user_id'];
		$now = date('Y-m-d H:i:s', time());
		$timeStamp = time();
		$beforeWeek = strtotime("-1weeks", strtotime($now));
		$list = [];
		while ($beforeWeek < $timeStamp) {
			$date = date('Y-m-d', $timeStamp);
			$timeStamp -= 86400;
			$royalty = $this->getUserStoreTodayRoyalty($userId, $storeId, [], $date);
			$list[] = [
				'date' => $date,
				'royalty' => $royalty
			];
		}
		return $list;
	}


	/**
	 * 计算某店铺的某天的人员所有/平均工资
	 * @param $storeId        @店铺id
	 * @param array $type 提成分类 []为空的话就是所有分类 或者指定特定的分类
	 * @param $date           @计算那一天的数据
	 * @param bool $isAverage 是否是员工的平均工资
	 * @return float
	 */
	public function userSalary($storeId, $type = [], $date, $isAverage = false)
	{
		// 获取店铺所有员工
		$usersId = (new StoreRepository())->getBarbersIds($storeId);
		// 服务提成 今日提成
		$todayRoyalty = $this->getUserStoreTodayRoyalty(0, $storeId, $type, $date);
		//人员基本工资
		$peopleSalary = empty($usersId) ? 0 : (new EmployeeRepository())->getStoreDailySalary($usersId, $storeId, config('constant.role.barber'), strtotime($date));

		$userSalary = $todayRoyalty['amount'] + $peopleSalary;

		return !$isAverage ? round(floatval($userSalary), 2) : (empty($usersId) ? 0 : round((floatval($userSalary) / count($usersId)), 2));

	}

	/**
	 * 计算理发师提成根据item_id
	 * @param $storeId
	 * @param $type
	 * @param $barberId
	 * @param $itemIds
	 * @param $date
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getDataBySource($storeId, $type, $barberId, $itemIds, $date)
	{

		return $this->pushCriteria(new  getRoyaltyDataCriteria($storeId, $type, $barberId, $itemIds, $date))->first();
	}


    /**
     * 获取理发师到某日之前的提成
     * @param $user_id
     * @param $store_id
     * @param $end_day
     */
    public function getBarberRoyaltyDate($user_id, $store_id, $end_day)
    {
        return $this->model->where('user_id', $user_id)
            ->whereDate('created_at', '>=', $end_day)
            ->where('store_id', $store_id)
            ->get();
    }

    /**
     * 获取理发师到某日之前的分类提成
     * @param $user_id
     * @param $store_id
     * @param $end_day
     */
    public function getBarberRoyaltyDateGroup($user_id, $store_id, $end_day)
    {
        return $this->model
            ->selectRaw('type,sum(amount) as royalty , sum(price) as amount , count(*) as count')
            ->where('user_id', $user_id)
            ->whereDate('created_at', '>=', $end_day)
            ->where('store_id', $store_id)
            ->groupBy('type')
            ->get();
    }

	/**
	 * 获取理发师到某日之前的提成分组
	 * @param $user_id
	 * @param $store_id
	 * @param $end_day
	 */
	public function getBarberRoyaltyDetailDate($store_id, $user_id, $end_day)
	{
		return $this->model
			->selectRaw('sum(amount) as amount,type')
			->where('user_id', $user_id)
			->whereDate('created_at', '>=', $end_day)
			->where('store_id', $store_id)
			->groupBy('type')
			->get();
	}

	/**
	 * 获取理发师到某日之前的服务提成明细
	 * @param $user_id
	 * @param $store_id
	 * @param $end_day
	 */
	public function getBarberRoyaltyServiceDetailDate($store_id, $user_id, $end_day)
	{
	    $select = [
            'hx_picture.image',
            'hx_store_service.name as title',
            'hx_royalty.amount',
            'hx_royalty.created_at'
        ];

	    $select = implode($select,',');

		return $this->model
			->selectRaw($select)
            ->leftJoin('order','order.id','royalty.item_id')
            ->leftJoin('order_item','order_item.order_id','order.id')
            ->leftJoin('store_service','store_service.id','order_item.service_id')
            ->leftJoin('dictionary_item','dictionary_item.id','store_service.type')
            ->leftJoin('picture','picture.id','dictionary_item.resource')
			->where('royalty.user_id', $user_id)
			->whereDate('royalty.created_at', '>=', $end_day)
			->where('royalty.store_id', $store_id)
			->where('royalty.type', 1)
            ->orderBy('royalty.created_at', 'DESC');
	}

	/**
	 * 获取理发师到某日之前的服务提成明细
	 * @param $user_id
	 * @param $store_id
	 * @param $end_day
	 */
	public function getBarberRoyaltyGoodsOrderDetailDate($store_id, $user_id, $end_day)
	{
        $select = [
            'hx_picture.image',
            'hx_goods.name as title',
            'hx_royalty.amount',
            'hx_royalty.created_at'
        ];

        $select = implode($select,',');

        return $this->model
            ->selectRaw($select)
            ->leftJoin('goods_order','goods_order.id','royalty.item_id')
            ->leftJoin('goods','goods.id','goods_order.goods_id')
            ->leftJoin('picture','picture.id','goods.image')
			->where('royalty.user_id', $user_id)
			->whereDate('royalty.created_at', '>=', $end_day)
			->where('royalty.store_id', $store_id)
			->where('royalty.type', 3)
            ->orderBy('royalty.created_at', 'DESC');
	}

	/**
	 * 获取理发师到某日之前的办卡提成明细
	 * @param $user_id
	 * @param $store_id
	 * @param $end_day
	 */
	public function getBarberRoyaltyMemberCardDetailDate($store_id, $user_id, $end_day)
	{
        $select = [
            '"'.config('constant.message.wx_image').'" as image',
            'hx_card_type.name as title',
            'hx_royalty.amount',
            'hx_royalty.created_at'
        ];

        $select = implode($select,',');

        return $this->model
            ->selectRaw($select)
            ->leftJoin('member_card_flow','member_card_flow.id','royalty.item_id')
            ->leftJoin('member_card','member_card.id','member_card_flow.card_id')
            ->leftJoin('card_type','card_type.id','member_card.type_id')
			->where('royalty.user_id', $user_id)
			->whereDate('royalty.created_at', '>=', $end_day)
			->where('royalty.store_id', $store_id)
			->where('royalty.type', 2)
            ->orderBy('royalty.created_at', 'DESC');
	}

	public function getBarberMemberCardRoyalty($user_id, $store_id)
	{
		return $this->model
			->where('type', 2)
			->where('user_id', $user_id)
			->where('store_id', $store_id)
			->sum('amount');
	}

	/**
	 * 跑定时任务的计算总和
	 * @param $date
	 * @return array
	 */
	public function getStoreRoyaltyAmount($date)
	{
		$royaltyList = $this->model->selectRaw('store_id,sum(amount) as amount')->whereDate('created_at', $date)->groupBy('store_id')->get()->toArray();
		return empty($royaltyList) ? [] : array_column($royaltyList, null, 'store_id');
	}

	/**
	 * 创建提成记录
	 * @param $user_id
	 * @param $store_id
	 * @param $type
	 * @param $item_id
	 * @param $price
	 * @param $rate
	 * @param $royalty
	 * @return mixed
	 */
	public function createRoyalty($user_id, $store_id, $type, $item_id, $price, $rate, $royalty)
	{
		$data = [
			'user_id' => $user_id,
			'store_id' => $store_id,
			'type' => $type,
			'item_id' => $item_id,
			'status' => 1,
			'item_type'=> $type ==1 ? Order::class : $type==2 ? MemberCard::class : GoodsOrder::class,
			'price' => $price,
			'rate' => $rate,
			'amount' => $royalty
		];

		return $this->create($data);
	}

	/**
	 * 计算员工提成
	 * @param $dateList
	 * @param $storeId
	 * @return mixed
	 */
	public function getEmployeeRoyalty($dateList,$storeId){
		return $this->model
			->where('store_id','=',$storeId)
			->whereDate('created_at','>=',$dateList['end_date'])
			->whereDate('created_at','<=',$dateList['start_date'])
			->sum('amount');
	}

	/**
	 * 员工业绩统计
	 * @param $dateList
	 * @param $storeId
	 * @return array
	 */
	public function getStoreAchievement($dateList, $storeId)
	{
		$list = $this->model
			->selectRaw('sum(hx_royalty.check_amount) as amount,count(hx_royalty.id) as count, hx_royalty.user_id')
			->where(['store_id' => $storeId])
			->whereDate('created_at', '>=', $dateList['end_date'])
			->whereDate('created_at', '<=', $dateList['start_date'])
			->groupBy('user_id')
			->get()
			->toArray();

		return empty($list) ? $list : array_column($list, null, 'user_id');
	}
}